﻿// 让元素自由移动
var MoveElem = new Class({
    initialize: function (options) {
        if (!this.setOptions(options)) return null

        this._move = apply(this, this.move);
        this._mouseup = apply(this, this.mouseup);
        //设置元素为绝对定位
        this.Main.css("position", "absolute");
        //给触发移动的元素绑定 mousedown 事件
        this.DragElem.bind("mousedown", apply(this, this.mousedown));
    },
    setOptions: function (options) {
        //既没有传入参数id，也没有传入参数elem，则退出
        if (!options.id && !options.$elem[0]) return 0;

        this.options = {
            id: "",
            dragElemId: "",
            $elem: null,
            $dragElem: null
        };
        extend(this.options, options || {});

        //同时传入参数id、$elem的情况下，优先使用$elem
        this.Main = this.options.$elem || $("#" + this.options.id);

        //优先级：this.options.$dragElem -> this.options.dragElemId -> this.Main
        this.DragElem = this.options.$dragElem ? this.options.$dragElem :
            this.options.dragElemId ? $("#" + this.options.dragElemId) : this.Main;
        return 1;
    },
    mousedown: function (event) {
        var e = window.event || event;
        //记录鼠标相对于移动元素的x轴偏移值
        this._offsetX = e.layerX || e.offsetX || 0;
        //记录鼠标相对于移动元素的y轴偏移值
        this._offsetY = e.layerY || e.offsetY || 0;

        //给 document 绑定 mousemove、mouseup 事件
        $(document).bind("mousemove", this._move).bind("mouseup", this._mouseup);
        Sys.ie ? this.Main[0].setCapture() : e.preventDefault();
    },
    move: function (event) {
        var o = getScroll();
        var e = window.event || event, x = e.clientX - this._offsetX + o.left, y = e.clientY - this._offsetY + o.top;
        this.Main.css({ left: x + "px", top: y + "px" });
    },
    mouseup: function (event) {
        //给 document 解除绑定 mousemove、mouseup 事件
        $(document).unbind("mousemove", this._move).unbind("mouseup", this._mouseup);
        if (Sys.ie) this.Main[0].releaseCapture();
    }
});
function center(elem) {
    var scrollY = Sys.ie ? document.documentElement.scrollTop : pageYOffset;
    var left = document.documentElement.clientWidth - elem.offsetWidth < 0 ? 0 : (document.documentElement.clientWidth - elem.offsetWidth) / 2;
    var top = document.documentElement.clientHeight - elem.offsetHeight < 0 ? 0 : (document.documentElement.clientHeight - elem.offsetHeight) / 2 + scrollY;

    elem.style.left = left + "px";
    elem.style.top = top + "px";
}
//创建一个模块
var Module = new Class({
    initialize: function (options) {
        this.setOptions(options);
        this.create();
    },
    setOptions: function (options) {
        this.options = {
            x: 0,
            y: 0,
            width: 215,
            height: 0,
            title: "新建模块",
            contents: [],
            onload: function () { }
        };
        extend(this.options, options || {});
    },
    create: function () {
        this.M = $('<div class="module" style="display:none;"></div>');
        this.Title = $('<div></div>');
        this.CloseBtn = $('<span>X</span>').bind("mousedown", apply(this, this.close));
        this.Main = $('<div></div>');

        this.setX(this.options.x);
        this.setY(this.options.y);
        this.setWidth(this.options.width);
        this.setHeight(this.options.height);
        this.setTitle(this.options.title);

        this.appendContent(this.options.contents);

        this.M.append(this.Title.append(this.CloseBtn)).append(this.Main).appendTo(document.body).show();
        new MoveElem({ $elem: this.M, $dragElem: this.Title });
        this.run(this.options.onload);
    },
    run: function (fn) {
        fn.apply(this);
    },
    setX: function (val) {
        this.M.css("left", val + "px");
    },
    setY: function (val) {
        this.M.css("top", val + "px");
    },
    setWidth: function (val) {
        this.M.width(val);
    },
    setHeight: function (val) {
        if (val) {
            this.M.height(val);
            this.Main.height(val - 45);
        }
    },
    setTitle: function (val) {
        this.Title.text(val);
    },
    appendContent: function (elems) {
        for (var i = 0; i < elems.length; i++) {
            this.Main.append(elems[i]);
        }
    },
    close: function () {
        this.M.remove();
    }
});

var Range = new Class({
    initialize: function (options) {
        this.setOptions(options);
        this.create();
    },
    setOptions: function (options) {
        this.options = {
            width: 120,     //记录滑动条宽度
            blockWidth: 13, //记录滑动块宽度
            minVal: 1,
            maxVal: 100,
            initVal: 1,
            valShowElemId: "",
            onchange: function () { },
            onmouseup: function () { }
        };
        extend(this.options, options || {});
    },
    create: function () {
        this.Range = $('<div class="rangeBar"></div>');
        //获取滑动块元素
        this.RangeBlock = $('<div></div>');
        this.Range.append(this.RangeBlock);
        //设置间隔值
        this.setInterval(this.options.minVal, this.options.maxVal);
        //记录上一次滑动条值
        this.preVal = this.curVal = this.options.initVal;
        //设置滑动块初始值
        this.setCurrentVal(this.options.initVal);
    },
    bindEvent: function () {
        this._move = apply(this, this.move);
        this._mouseup = apply(this, this.mouseup);
        //给滑动条绑定 mousedown 事件
        this.Range.bind("mousedown", apply(this, this.mousedown));
        //给滑动块绑定 mousedown 事件
        this.RangeBlock.bind("mousedown", apply(this, this.mousedown));

        if (this.options.valShowElemId) {
            this.ValShowElem = $("#" + this.options.valShowElemId);
            this.ValShowElem.text(this.curVal);
        }
    },
    mousedown: function (event) {
        var e = window.event || event, target = e.target || e.srcElement;

        if (target == this.Range[0]) {
            this._offsetX = 7;
            this.moveTo(e, this.Range[0]);
        } else if (target == this.RangeBlock[0]) {
            //记录鼠标相对于移动元素的x轴偏移值
            this._offsetX = e.layerX || e.offsetX;
        }

        //给 document 绑定 mousemove、mouseup 事件
        $(document).bind("mousemove", this._move).bind("mouseup", this._mouseup);
        Sys.ie ? this.RangeBlock[0].setCapture() : e.preventDefault();
        e.stopPropagation();
    },
    move: function (event) {
        this.moveTo(window.event || event, this.RangeBlock[0]);
    },
    moveTo: function (e, elem) {
        //获取滑动块相对于 body 的坐标
        var pos = getClientRect(elem);
        var x = e.clientX - this._offsetX - pos.left - 10;

        //固定滑动块位置在滑动条内
        if (x < 0) x = 0;
        else if (x > this.options.width - this.options.blockWidth) x = this.options.width - this.options.blockWidth;

        this.RangeBlock.css({ left: x + "px" });

        //计算数值
        var val = Math.round(x / this.Interval) + this.options.minVal;
        if (val != this.preVal) {
            this.preVal = this.curVal;
            this.curVal = val;

            if (this.ValShowElem) this.ValShowElem.text(val);
            //触发onchange函数
            this.options.onchange.apply(this);
        }
    },
    mouseup: function (event) {
        //给 document 解除绑定 mousemove、mouseup 事件
        $(document).unbind("mousemove", this._move).unbind("mouseup", this._mouseup);
        Sys.ie && this.RangeBlock[0].releaseCapture();
        //触发onmouseup函数
        this.options.onmouseup.apply(this);
    },
    setInterval: function (minVal, maxVal) {
        //设置间隔值
        this.Interval = (this.options.width - this.options.blockWidth) / (maxVal - minVal);
    },
    setCurrentVal: function (val) {
        //设置滑动块初始位置
        this.RangeBlock.css("left", (val - this.options.minVal) * this.Interval + "px");
    }
});

var Tool = new Class({
    initialize: function (options) {
        this.setOptions(options);
    },
    setOptions: function (options) {
        this.options = {
            type: "",
            ctx: canvas.main.ctx,
            diameter: 1,
            hardness: 100,
            flow: 100,
            opacity: 100,
            draw: function () { }
        };
        extend(this.options, options || {});
    },
    load: function () {
        tool.current = this;
        updateBrush();
        m_option.M.show();
        new Options();
        canvas.temp[0].style.cursor='url(img/'+this.options.type+'_2.png),pointer';
    },
    set: function (opt, val) {
        var min = 1,
            max = gui_options[this.options.type][opt];
        if (val >= min && val <= max) {
            this.options[opt] = val;
            updateBrush();
        }
    },
    setdiameter: function (val) {
        this.set("diameter", val);
    },
    sethardness: function (val) {
        this.set("hardness", val);
    },
    setflow: function (val) {
        this.set("flow", val);
    },
    setopacity: function (val) {
        this.set("opacity", val);
    },
    down: function () {
        this.draw(0, 0);
    },
    draw: function (x, y) {
        this.options.draw.apply(this, arguments);
    },
    move: function () {
        createFlow(apply(this, this.draw));
        startX = canvasPos.x;
        startY = canvasPos.y;
    }
});
var Shape = new Class({
    initialize: function (options) {
        this.setOptions(options);
    },
    setOptions: function (options) {
        this.options = {
            type: "",
            ctx: canvas.temp.ctx,
            diameter: 1,
            opacity: 100,
            move: function () { },
            down: function () { }
        };
        extend(this.options, options || {});
    },
    load: function () {
        tool.current = this;
        this.options.ctx.lineWidth = this.options.diameter;
        this.options.ctx.globalAlpha = this.options.opacity / 100;
        if (this.options.type != "picker") {
            new Options();
            m_option.M.show();
        }
        else m_option.M.hide();
    },
    set: function (opt, val, cb) {
        var min = 1,
            max = gui_options[this.options.type][opt];
        if (val >= min && val <= max) {
            this.options[opt] = val;
            cb.apply(this, [val]);
        }
    },
    setdiameter: function (val) {
        this.set("diameter", val, function (v) {
            this.options.ctx.lineWidth = v;
        });
    },
    setopacity: function (val) {
        this.set("opacity", val, function (v) {
            this.options.ctx.globalAlpha = v / 100;
        });
    },
    down: function (e) {
        this.options.down.apply(this, arguments);
    },
    move: function () {
        this.options.move.apply(this);
    }
});
var Options = new Class({
    initialize: function () {
        var t = tool.current,
            options = gui_options[t.options.type].build;

        m_option.setTitle(cn[t.options.type]);
        m_option.Main.html("");
        for (var index in options) {
            (function () {
                var opt = options[index],
                arg = gui_options[t.options.type];

                // 滑动条
                var range = new Range({
                    maxVal: arg[opt],
                    initVal: t.options[opt],
                    valShowElemId: t.options.type + "_" + opt,
                    onmouseup: function () {
                        t["set" + opt](this.curVal);
                    }
                });
                m_option.appendContent([
                    '<div>' + cn[opt] + '</div>',
                    $('<div style="margin:2px 0;overflow:hidden;"></div>').append(range.Range).append('<span id="' + range.options.valShowElemId + '" style="margin-left:20px;color:#fff;"></span>')
                ]);
                range.bindEvent();
            })(index);
        }
    }
});